<script setup>
import { ref } from 'vue'

let selection = null
let range = null

const expalamP = ref(null)

const onGetSelection = () => {
    selection = window.getSelection()
    range = selection.getRangeAt(0)

    console.log(selection.toString())
    console.log(selection)
    console.log(range)
}

const onSetSelection = () => {
    selection = window.getSelection()
    range = document.createRange()

    // 如果起始节点类型是 Text ， Comment , or CDATASection 之一, 那么 startOffset 指的是从起始节点算起字符的偏移量
    // 对于其他 Node 类型节点， startOffset 是指从起始结点开始算起子节点的偏移量
    range.setStart(expalamP.value.firstChild, 0)
    range.setEnd(expalamP.value.firstChild, 2)
    selection.removeAllRanges()
    selection.addRange(range)
}

const onSetNodeSelection = () => {
    selection = window.getSelection()
    range = document.createRange()

    // 选中整个节点，在富文本中删除会删除整个节点
    range.selectNode(expalamP.value.childNodes[1])

    // 选中节点内容，在富文本中删除会删除内容但会保留节点
    range.selectNodeContents(expalamP.value.childNodes[1])

    selection.removeAllRanges()
    selection.addRange(range)
}
</script>

<template>
    <div class="selection-wraper">
        <div>
            <p ref="expalamP">想搞清楚这个，不得不提到两个重要的对象：<a href="https://link.segmentfault.com" rel="nofollow" target="_blank">Selection</a> 和 <a href="https://link.segmentfault.com" rel="nofollow" target="_blank">Range</a>。这两个对象都有大量的属性和方法，详细可以查看官方文档，这里简单介绍一下：</p>
            
            <ol>
                <li><strong>Selection</strong> 对象表示用户选择的文本范围或插入符号的当前位置。它代表页面中的文本选区，可能横跨多个元素。通常由用户拖拽鼠标经过文字而产生。</li>
                <li><strong>Range</strong>对象表示包含节点和部分文本节点的文档片段。通过 <code>selection</code> 对象获得的 <code>range</code> 对象才是我们操作光标的重点。</li>
            </ol>
        </div>

        <hr class="hr-solid-content" data-content="API">

        <div class="toolbar">
            <div>
                <div>通过let selection = window.getSelection()获取当前选区，selection.getRangeAt(0)获取选区具体节点信息</div>
                <el-button type="primary" @click="onGetSelection">获取选区</el-button>
            </div>

            <div>
                <div>通过let selection = window.getSelection()获取当前选区，document.createRange(), range.setStart(),range.setEnd(), selection.addRange(range)来设置选区</div>
                <el-button type="primary" @click="onSetSelection">设置文本选区</el-button>
                <el-button type="primary" @click="onSetNodeSelection">设置节点选区</el-button>
            </div>
            <div>
                <img style="width: 100%; max-width: 800px;" src="../../assets/selection/1.webp">
                <img style="width: 100%; max-width: 800px;" src="../../assets/selection/2.webp">
            </div>
        </div>
    </div>
</template>

<style scoped>
.selection-wraper {
    height: 100%;
    padding: 10px;
    overflow: auto;
}

.toolbar {
    display: flex;
    flex-direction: column;
    padding: 8px;
}
</style>